package com.snopy.reference.soft;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.concurrent.TimeUnit;

/**
 * @author snopy
 * @version 1.0.0
 * @classname SoftReferenceDemo
 * @description 软引用，jvm在内存不够即将发生OOM时会清理软引用，正常gc不会不会将其清理
 * @email 77912204@qq.com
 * @date 2022/03/16 0:26
 */
public class SoftReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<ClassMemory> queue = new ReferenceQueue<>();
        SoftReference<ClassMemory> m1 = new SoftReference<>(new ClassMemory(),queue);
        new Thread(new CleanTask(queue)).start();
        System.out.println("m1"+m1.get());
        System.out.println("-------"+queue.poll());
        //gc不会清理软引用
        System.gc();
        System.out.println("+++++++"+queue.poll());
        System.out.println("m1"+m1.get());
        SoftReference<ClassMemory> m2 = new SoftReference<>(new ClassMemory());
        System.out.println("m2"+m2.get());
        SoftReference<ClassMemory> m3 = new SoftReference<>(new ClassMemory());
        System.out.println("m3"+m3.get());
        SoftReference<ClassMemory> m4 = new SoftReference<>(new ClassMemory());
        System.out.println("m4"+m4.get());
        SoftReference<ClassMemory> m5 = new SoftReference<>(new ClassMemory());
        System.out.println("m5"+m5.get());

        SoftReference<ClassMemory> m6 = new SoftReference<>(new ClassMemory());
        System.out.println("m6"+m6.get());
        SoftReference<ClassMemory> m7 = new SoftReference<>(new ClassMemory());
        System.out.println("m7"+m7.get());

        System.gc();
        TimeUnit.SECONDS.sleep(3);


        System.out.println(queue.poll());

        TimeUnit.SECONDS.sleep(3);
        SoftReference<ClassMemory> m8 = new SoftReference<>(new ClassMemory());
        System.out.println("m8"+m8.get());
        SoftReference<ClassMemory> m9 = new SoftReference<>(new ClassMemory());
        System.out.println("m9"+m9.get());
        TimeUnit.SECONDS.sleep(3);
        SoftReference<ClassMemory> m18 = new SoftReference<>(new ClassMemory());
        System.out.println("m18"+m18.get());
        SoftReference<ClassMemory> m19 = new SoftReference<>(new ClassMemory());
        System.out.println("m19"+m19.get());
    }
}
/**
 * 模拟1M内存
 */
class ClassMemory{
    private final byte[] memory = new byte[1048576];
    public void sayInfo(){
        System.out.println("hello");
    }
}
class CleanTask implements Runnable{
    ReferenceQueue<ClassMemory> queue;

    public CleanTask(ReferenceQueue<ClassMemory> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        System.out.println("开启清理监听---");
        SoftReference<ClassMemory> sr;
        while (true){
            try {
                TimeUnit.MILLISECONDS.sleep(10);
                if ((sr = (SoftReference<ClassMemory>) queue.poll()) != null){
                    System.out.println("execute clean---------");
                    break;
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}